package com.hty.filemanager;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.format.Formatter;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    ListView listView;
    String path = "/", title = "";
    SimpleAdapter adapter;
    ArrayList<HashMap<String, Object>> list_file = new ArrayList<>();
    SimpleDateFormat SDF = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.getDefault());
    int order = 0, position = 0;
    SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        android.support.v7.app.ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setHomeButtonEnabled(true);
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        order = sharedPreferences.getInt("order", 0);
        listView = findViewById(R.id.listView_file);
        adapter = new SimpleAdapter(this, list_file, R.layout.item, new String[]{ "icon", "name", "size", "time" }, new int[]{ R.id.imageView_icon, R.id.textView_name, R.id.textView_size, R.id.textView_time });
        listView.setAdapter(adapter);
        adapter.setViewBinder(new SimpleAdapter.ViewBinder() {
            @Override
            public boolean setViewValue(View view, Object data, String arg2) {
                if (view instanceof ImageView && data instanceof String) {
                    String fp = (String) data;
                    String mime = URLConnection.getFileNameMap().getContentTypeFor(fp);
                    //Log.e(Thread.currentThread().getStackTrace()[2] + "", fp);
                    int id = queryIDByPath(fp);
                    if (mime == null) {
                        ((ImageView) view).setImageResource(R.mipmap.file);
                    } else if (mime.startsWith("video/")) {
                        Bitmap bitmap = MediaStore.Video.Thumbnails.getThumbnail(getContentResolver(), id, MediaStore.Video.Thumbnails.MINI_KIND, null);
                        if (bitmap != null)
                            ((ImageView) view).setImageBitmap(bitmap);
                        else
                            ((ImageView) view).setImageResource(R.mipmap.video);
                    } else if (mime.startsWith("image/")) {
                        Bitmap bitmap = MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(), id, MediaStore.Images.Thumbnails.MINI_KIND, null);
                        if (bitmap != null)
                            ((ImageView) view).setImageBitmap(bitmap);
                        else
                            ((ImageView) view).setImageResource(R.mipmap.image);
                    }  else if (mime.startsWith("audio/")) {
                        ((ImageView) view).setImageResource(R.mipmap.audiofile);
                    } else if (mime.equals("text/plain")) {
                        ((ImageView) view).setImageResource(R.mipmap.txtfile);
                    } else if (mime.equals("text/html")) {
                        ((ImageView) view).setImageResource(R.mipmap.htmlfile);
                    } else if (mime.equals("application/msword")) {
                        ((ImageView) view).setImageResource(R.mipmap.docfile);
                    } else if (mime.equals("application/pdf")) {
                        ((ImageView) view).setImageResource(R.mipmap.pdffile);
                    } else if (mime.equals("application/x-tar") || mime.equals("application/zip") || mime.equals("application/x-gzip")) {
                        ((ImageView) view).setImageResource(R.mipmap.zipfile);
                    } else {
                        ((ImageView) view).setImageResource(R.mipmap.file);
                    }
                    return true;
                } else {
                    return false;
                }
            }
        });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                String name = ((TextView) arg1.findViewById(R.id.textView_name)).getText().toString();
                String path1;
                if (path.equals(File.separator)) {
                    path1 = path + name;
                } else {
                    path1 = path + File.separator + name;
                }
                File file = new File(path1);
                if (file.exists()) {
                    position = arg2;
                    if (file.isDirectory()) {
                        path = path1;
                        genList(path);
                    } else {
                        String mime = URLConnection.getFileNameMap().getContentTypeFor(path1);
                        if (mime == null)
                            mime = "*/*";
                        Intent intent = new Intent(Intent.ACTION_VIEW);
                        intent.setDataAndType(Uri.fromFile(new File(path1)), mime);
                        startActivity(intent);
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "文件或路径不存在", Toast.LENGTH_SHORT).show();
                }

            }
        });
        listView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
            @Override
            public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
                AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
                title = ((TextView) info.targetView.findViewById(R.id.textView_name)).getText().toString();
                menu.setHeaderTitle(title);
                menu.add(0, 0, 0, "复制");
                menu.add(0, 1, 1, "剪切");
                menu.add(0, 2, 2, "重命名");
                menu.add(0, 3, 3, "属性");
                menu.add(0, 4, 4, "分享");
                menu.add(0, 5, 5, "删除");
                menu.add(0, 6, 6, "编辑");
                menu.add(0, 7, 7, "添加书签");
            }
        });

        Intent intent = getIntent();
        path = intent.getStringExtra("Path");
        position = intent.getIntExtra("Position", 0);
        if (path == null)
            path = "/";
        Log.e(Thread.currentThread().getStackTrace()[2] + "", path);
        genList(path);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        //AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        switch (item.getItemId()) {
            case 0:
                Toast.makeText(getApplicationContext(), "复制", Toast.LENGTH_SHORT).show();
                break;
            case 1:
                Toast.makeText(getApplicationContext(), "剪切", Toast.LENGTH_SHORT).show();
                break;
            case 2:
                final EditText editText = new EditText(MainActivity.this);
                editText.setText(title);
                AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
                dialog.setTitle("重命名").setView(editText);
                dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String path1, path2;
                        if (path.equals(File.separator)) {
                            path1 = path + title;
                            path2 = path + editText.getText().toString();
                        } else {
                            path1 = path + File.separator + title;
                            path2 = path + File.separator + editText.getText().toString();
                        }
                        File file = new File(path1);
                        boolean bool = file.renameTo(new File(path2));
                        if (bool) {
                            Toast.makeText(MainActivity.this, title + " 重命名为 " + editText.getText().toString() + " 成功", Toast.LENGTH_SHORT).show();
                            MediaScannerConnection.scanFile(MainActivity.this, new String[]{ path2 }, null, null);
                            position = listView.getFirstVisiblePosition();
                            genList(path);
                        } else {
                            Toast.makeText(MainActivity.this, title + " 重命名为 " + editText.getText().toString() + " 失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
                dialog.setNegativeButton("取消", null).show();
                break;
            case 3:
                String path1;
                if (path.equals(File.separator)) {
                    path1 = path + title;
                } else {
                    path1 = path + File.separator + title;
                }
                File file = new File(path1);
                String mime = URLConnection.getFileNameMap().getContentTypeFor(path1);
                Date datec = new Date(file.lastModified());
                new AlertDialog.Builder(this).setIcon(R.mipmap.ic_launcher).setTitle("属性").setMessage(String.format(String.format("文件路径：" + path1 + "\n创建时间：" + SDF.format(datec) + "\n类型：" + mime + "\n大小：" + Formatter.formatFileSize(this, file.length())))).setPositiveButton("确定", null).show();
                break;
            case 4:
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_SEND);
                intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(path + "/" + title)));
                intent.setType("*/*");
                startActivity(Intent.createChooser(intent, "分享 " + title));
                break;
            case 5:
                if (path.equals(File.separator)) {
                    path1 = path + title;
                } else {
                    path1 = path + File.separator + title;
                }
                file = new File(path1);
                boolean b = file.delete();
                if (b) {
                    position = listView.getFirstVisiblePosition();
                    genList(path);
                }
                break;
            case 6:
                if (path.equals(File.separator)) {
                    path1 = path + title;
                } else {
                    path1 = path + File.separator + title;
                }
                intent = new Intent(MainActivity.this, TexteditActivity.class);
                intent.putExtra("Path", path1);
                startActivity(intent);
                break;
            case 7:
                if (path.equals(File.separator)) {
                    path1 = path + title;
                } else {
                    path1 = path + File.separator + title;
                }
                Utils.writeFile("bookmarks.txt", "\n" + path1, MODE_APPEND);
                break;
        }
        return true;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        String[] sm = { "新建", "排序", "书签", "刷新", "搜索", "设置" };
        for (int i=0; i<sm.length; i++) {
            menu.add(0, i, i, sm[i]);
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int item_id = item.getItemId();
        switch (item_id) {
            case 0:
                final String[] items = { "文件", "文件夹" };
                AlertDialog.Builder dialog = new AlertDialog.Builder(this);
                dialog.setTitle("新建");
                dialog.setSingleChoiceItems(items, order, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case 0:
                                AlertDialog.Builder dialog0 = new AlertDialog.Builder(MainActivity.this);
                                dialog0.setTitle("新建文件 - 名称：");
                                final EditText editText0 = new EditText(MainActivity.this);
                                dialog0.setView(editText0);
                                dialog0.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        String filename = editText0.getText().toString();
                                        File file = new File(path + File.separator + filename);
                                        try {
                                            Boolean bool = file.createNewFile();
                                            if (bool) {
                                                Toast.makeText(MainActivity.this, "文件" + file.getName() + " 创建成功", Toast.LENGTH_SHORT).show();
                                                MediaScannerConnection.scanFile(MainActivity.this, new String[]{ file.getAbsolutePath() }, null, null);
                                                genList(path);
                                            } else {
                                                Toast.makeText(MainActivity.this, "文件" + file.getName() + " 创建失败", Toast.LENGTH_SHORT).show();
                                            }
                                        } catch (Exception e) {
                                            Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                });
                                dialog0.setNegativeButton("取消", null);
                                dialog0.show();
                                break;
                            case 1:
                                AlertDialog.Builder dialog1 = new AlertDialog.Builder(MainActivity.this);
                                dialog1.setTitle("新建文件夹 - 名称：");
                                final EditText editText1 = new EditText(MainActivity.this);
                                dialog1.setView(editText1);
                                dialog1.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        String filename = editText1.getText().toString();
                                        File file = new File(path + File.separator + filename);
                                        Boolean bool = file.mkdir();
                                        if (bool) {
                                            Toast.makeText(MainActivity.this, "文件夹" + file.getName() + " 创建成功", Toast.LENGTH_SHORT).show();
                                            genList(path);
                                        } else {
                                            Toast.makeText(MainActivity.this, "文件夹" + file.getName() + " 创建失败", Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                });
                                dialog1.setNegativeButton("取消", null);
                                dialog1.show();
                                break;
                        }
                        dialog.dismiss();
                    }
                });
                dialog.show();
                break;
            case 1:
                final String[] items1 = { "文件名", "时间", "大小", "文件名（倒序）", "时间（倒序）", "大小（倒序）", "文件夹在前" , "文件在前" };
                dialog = new AlertDialog.Builder(this);
                dialog.setTitle("排序");
                dialog.setSingleChoiceItems(items1, order, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (which < 6) {
                            order = which;
                            SharedPreferences.Editor SPE = sharedPreferences.edit();
                            SPE.putInt("order", order);
                            SPE.commit();
                        } else {
                            boolean b = false;
                            if (which == 6)
                                b = true;
                            else if (which == 7)
                                b = false;
                            SharedPreferences.Editor SPE = sharedPreferences.edit();
                            SPE.putBoolean("switch_dirFirst", b);
                            SPE.commit();
                        }
                        Toast.makeText(MainActivity.this, "按 " + items1[which] + " 排序", Toast.LENGTH_SHORT).show();
                        genList(path);
                        dialog.dismiss();
                    }
                });
                dialog.show();
                break;
            case 2:
                startActivity(new Intent(MainActivity.this, BookmarksActivity.class));
                break;
            case 3:
                position = listView.getFirstVisiblePosition();
                finish();
                Intent intent = new Intent(MainActivity.this, MainActivity.class);
                intent.putExtra("Path", path);
                intent.putExtra("Position", position);
                startActivity(intent);
                break;
            case 4:
                startActivity(new Intent(MainActivity.this, SearchActivity.class));
                break;
            case 5:
                startActivity(new Intent(MainActivity.this, SettingsActivity.class));
                break;
            case android.R.id.home:
                finish();
                break;
        }
        return true;
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (!path.equals("/")) {
                File file = new File(path);
                path = file.getParentFile().getAbsolutePath();
                genList(path);
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    void genList(String path1) {
        Log.e(Thread.currentThread().getStackTrace()[2] + "", path1);
        String filename = "";
        File file = new File(path1);
        if (file.isFile()) {
            filename = file.getName();
            path = path1.substring(0, path1.lastIndexOf(File.separator));
            file = new File(path);
        }
        Log.e(Thread.currentThread().getStackTrace()[2] + "", path);
        setTitle(path);
        list_file.clear();
        File[] files;
        if (sharedPreferences.getBoolean("switch_displayHide", false)) {
            files = file.listFiles();
        } else {
            files = file.listFiles(new FileFilterHide());
        }
        if (files != null) {
            if (order == 0) {
                Arrays.sort(files, new ComparatorName());
            } else if (order == 1) {
                Arrays.sort(files, new ComparatorTime());
            } else if (order == 2) {
                Arrays.sort(files, new ComparatorSize());
            } else if (order == 3) {
                Arrays.sort(files, new ComparatorNameDesc());
            } else if (order == 4) {
                Arrays.sort(files, new ComparatorTimeDesc());
            } else if (order == 5) {
                Arrays.sort(files, new ComparatorSizeDesc());
            }
            if (sharedPreferences.getBoolean("switch_dirFirst", false))
                Arrays.sort(files, new ComparatorDirFirst());
            else
                Arrays.sort(files, new ComparatorFileFirst());
            for (File file1 : files) {
                HashMap<String, Object> listItem = new HashMap<>();
                String size;
                if (file1.isDirectory()) {
                    listItem.put("icon", R.mipmap.folder);
                    File[] files1 = file1.listFiles();
                    if (files1 == null) {
                        size = "";
                    } else {
                        size = files1.length + "项";
                    }
                } else {
                    String mime = URLConnection.getFileNameMap().getContentTypeFor(file1.getAbsolutePath());
                    //Log.e(Thread.currentThread().getStackTrace()[2] + "", file1.getAbsolutePath() + ", " + mime);
                    if (mime == null) {
                        listItem.put("icon", R.mipmap.file);
                    } else if (mime.equals("text/plain")) {
                        listItem.put("icon", R.mipmap.txtfile);
                    } else if (mime.equals("text/html")) {
                        listItem.put("icon", R.mipmap.htmlfile);
                    } else if (mime.equals("application/pdf")) {
                        listItem.put("icon", R.mipmap.pdffile);
                    } else if (mime.equals("application/zip")) {
                        listItem.put("icon", R.mipmap.zipfile);
                    } else {
                        listItem.put("icon", file1.getAbsolutePath());
                    }
                    size = Formatter.formatFileSize(this, file1.length());
                }
                if (filename.equals(file1.getName()))
                    position = list_file.size();
                listItem.put("name", file1.getName());
                listItem.put("size", size);
                Date datec = new Date(file1.lastModified());
                listItem.put("time", SDF.format(datec));
                list_file.add(listItem);
            }
        }
        adapter.notifyDataSetChanged();
        listView.setSelection(position);
    }

    class ComparatorName implements Comparator<File> {
        public int compare(File f1, File f2) {
            return f1.getName().compareTo(f2.getName());
        }
    }

    class ComparatorNameDesc implements Comparator<File> {
        public int compare(File f1, File f2) {
            return f2.getName().compareTo(f1.getName());
        }
    }

    class ComparatorTime implements Comparator<File> {
        public int compare(File f1, File f2) {
            long diff = f1.lastModified() - f2.lastModified();
            if (diff > 0)
                return 1;
            else if (diff == 0)
                return 0;
            else
                return -1;
        }
    }

    class ComparatorTimeDesc implements Comparator<File> {
        public int compare(File f1, File f2) {
            long diff = f2.lastModified() - f1.lastModified();
            if (diff > 0)
                return 1;
            else if (diff == 0)
                return 0;
            else
                return -1;
        }
    }

    class ComparatorSize implements Comparator<File> {
        public int compare(File f1, File f2) {
            long diff = f1.length() - f2.length();
            if (diff > 0)
                return 1;
            else if (diff == 0)
                return 0;
            else
                return -1;
        }
    }

    class ComparatorDirFirst implements Comparator<File> {
        public int compare(File f1, File f2) {
            if (f1.isFile() && f2.isDirectory())
                return 1;
            else if (f1.isDirectory() && f2.isFile())
                return -1;
            else
                return 0;
        }
    }

    class ComparatorFileFirst implements Comparator<File> {
        public int compare(File f1, File f2) {
            if (f1.isFile() && f2.isDirectory())
                return -1;
            else if (f1.isDirectory() && f2.isFile())
                return 1;
            else
                return 0;
        }
    }

    class ComparatorSizeDesc implements Comparator<File> {
        public int compare(File f1, File f2) {
            long diff = f2.length() - f1.length();
            if (diff > 0)
                return 1;
            else if (diff == 0)
                return 0;
            else
                return -1;
        }
    }

    class FileFilterHide implements FileFilter {
        @Override
        public boolean accept(File pathname) {
            String filename = pathname.getName();
            if (filename.startsWith(".")) {
                return false;
            } else {
                return true;
            }
        }
    }

    int queryIDByPath(String fp) {
        //Log.e(Thread.currentThread().getStackTrace()[2] + "", fp);
        Uri uri = MediaStore.Files.getContentUri("external");
        String[] projection = new String[] { MediaStore.Files.FileColumns._ID };
        String selection = MediaStore.Files.FileColumns.DATA + "=?";
        String[] selectionArgs = new String[] { fp };
        Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, null);
        int id = -1;
        if (cursor.moveToFirst()) {
            id = cursor.getInt(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID));
        }
        cursor.close();
        return id;
    }

}
